#pragma once

#include <algorithm/analytical_model/algorithm/cuda/inter_op/Data.h>
#include <utils/config.h>

#include <memory>
#include <vector>


namespace solar::cuda
{
    class ShadowBlockCalculator;
}

namespace solar::cuda::inter_op
{
    class RectangleGrid;

    class ShadowBlockCalculator
    {
        public:
            ShadowBlockCalculator();
            void calculate() const;
            void init(FUNC_CONST_INPUT std::vector<Float3>& input_vertices) const;
            // Note: result data is stored on GPU
            [[nodiscard]] auto getResult() const -> Float4*;
            // Note: result data is stored on GPU
            [[nodiscard]] auto getMicroHeliostatShadowBlock() const -> bool*;
            [[nodiscard]] auto getMicroHeliostatShadowBlockPerRow() const -> bool*;
            [[nodiscard]] auto getCudaStream() const -> cudaStream_t;
            void setHelioRowCol(const Int2& row_col) const;
            void setGrid(RectangleGrid* grid) const;
            void setSunRayDirection(const Float3& direction) const;
            void calculateCenterBias(Float3* d_heliostat_positions) const;

        private:
            std::shared_ptr<::solar::cuda::ShadowBlockCalculator> delegate_ptr_;
    };
} // namespace solar::cuda::inter_op
